package com.ksvip.next.components.oss;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;

/**
 * oss 连接
 * 
 * @author liks 2019年9月19日 下午5:28:52
 */
public class OssUtils {
    private static final Logger                 logger        = LoggerFactory.getLogger(OssUtils.class);
    private static final Map<String, OSSClient> channelOssMap = new ConcurrentHashMap<String, OSSClient>();

    /**
     * 是否已连接
     * 
     * @return
     */
    private static OSSClient isConnected(final OssConfigVO ossConfigVO) {
        final String index = ossConfigVO.getBucket().concat("-").concat(ossConfigVO.getAccessKeyId());
        final OSSClient client = channelOssMap.get(index);
        logger.info("oss={},channelType={} ", client, index);
        if (null != client) {
            return client;
        } else {
            final OSSClient ossclient = getOss(ossConfigVO.getEndpoint(), ossConfigVO.getAccessKeyId(),
                    ossConfigVO.getAccessKeySecret(), ossConfigVO.getSecurityToken());
            channelOssMap.put(index, ossclient);
            return ossclient;
        }
    }

    private static void shutdown(final OssConfigVO ossConfigVO) {
        final String index = ossConfigVO.getBucket().concat("-").concat(ossConfigVO.getAccessKeyId());
        final OSSClient client = channelOssMap.get(index);
        if (null != client) {
            client.shutdown();
            channelOssMap.remove(index);
        }
    }

    /**
     * uploadFile
     * 
     * @param key
     * @param file
     * @return
     * @throws IOException
     * @throws IOException
     */
    public static String uploadFile(final OssConfigVO ossConfigVO, final String key, final File file)
            throws IOException {
        // 创建上传Object的Metadata
        final ObjectMetadata meta = new ObjectMetadata();
        final InputStream content = new FileInputStream(file);
        // 必须设置ContentLength
        meta.setContentLength(file.length());
        final OSSClient client = isConnected(ossConfigVO);
        // 上传Object.
        final PutObjectResult result = client.putObject(ossConfigVO.getBucket(), key, content, meta);
        content.close();
        shutdown(ossConfigVO);
        return result.getETag();
    }

    /**
     * 从OSS下载文件
     * 
     * @param filename
     * @param ossConfigVO objectname+文件
     * @param savefile
     * @throws IOException
     */
    public static void downloadFile(final OssConfigVO ossConfigVO, final String filename, final String savefile)
            throws IOException {
        final File file = new File(savefile);
        if (!file.getParentFile().isDirectory()) {
            file.getParentFile().mkdirs();
        }
        file.createNewFile();
        final OSSClient client = isConnected(ossConfigVO);
        // ossObject包含文件所在的存储空间名称、文件名称、文件元信息以及一个输入流。
        final OSSObject ossObject = client.getObject(ossConfigVO.getBucket(), filename);
        //获取到OSS文件 
        final InputStream is = ossObject.getObjectContent();
        final BufferedInputStream bis = new BufferedInputStream(is);
        final FileOutputStream fileOutputStream = new FileOutputStream(file);
        final BufferedOutputStream bos = new BufferedOutputStream(fileOutputStream);
        final int buffer = 1024; // 定义缓冲区的大小
        int length = 0;
        final byte[] b = new byte[buffer];
        while ((length = bis.read(b)) != -1) {
            bos.write(b, 0, length);
        }
        fileOutputStream.flush();
        bos.flush();
        bos.close();
        fileOutputStream.close();
        // 下载后删除oss的临时文件
        // client.deleteObject(bucketName, objectkey);
        shutdown(ossConfigVO);

    }

    /**
     * 获取链接
     * 
     * @return
     */
    private static OSSClient getOss(final String endpoint, final String accessKeyId, final String accessKeySecret,
                                    final String securityToken) {
        return (OSSClient) new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret, securityToken);
    }
}
